package com.xjgz.aio.socket.transport;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.util.concurrent.TimeUnit;

public abstract class AioSession {

    /**
     * session状态: 已关闭
     */
    protected static final byte SESSION_STATUS_CLOSED = 1;
    /**
     * session状态: 正在关闭
     */
    protected static final byte SESSION_STATUS_CLOSING = 2;
    /**
     * session状态: 已启用
     */
    protected static final byte SESSION_STATUS_ENABLED = 3;

    /**
     * 当前会话状态
     */
    protected byte status = SESSION_STATUS_ENABLED;

    /**
     * 是否读通知已至末尾
     */
    boolean eof;

    int modCount = 0;

    /**
     * 附件
     */
    private Object attachment;

    /**
     * 获取当前会话的写缓冲区
     */
    public abstract WriteBuffer writeBuffer();

    /**
     * 获取当前会话的读缓冲区
     */
    public abstract ByteBuffer readBuffer();

    /**
     * 异步关闭当前会话
     */
    public final void close() {
        close(true);
    }

    public abstract void awaitRead();

    /**
     * 继续触发读行为，该方法仅可在异步处理模式下使用，否则会触发不可预知的异常
     */
    public abstract void signalRead();

    /**
     * 关闭当前会话
     */
    public abstract void close(boolean immediate);

    /**
     * 获取当前会话的ID
     */
    public String getSessionID() {
        return "aioSession-" + hashCode();
    }

    /**
     * 判断当前会话是否已失效
     */
    public boolean isInvalid() {
        return status != SESSION_STATUS_ENABLED;
    }

    /**
     * 获取附件
     */
    @SuppressWarnings("unchecked")
    public final <A> A getAttachment() {
        return (A) attachment;
    }

    /**
     * 存放附件
     */
    public final <A> void setAttachment(A attachment) {
        this.attachment = attachment;
    }

    /**
     * 获取当前会话的本地连接地址
     */
    public abstract InetSocketAddress getLocalAddress() throws IOException;

    /**
     * 获取当前会话的远程连接地址
     */
    public abstract InetSocketAddress getRemoteAddress() throws IOException;

    /**
     * 执行同步读操作
     */
    public final int read() throws IOException {
        return read(0, TimeUnit.MICROSECONDS);
    }

    /**
     * 执行同步读操作
     */
    public int read(long timeout, TimeUnit unit) throws IOException {
        throw new UnsupportedOperationException();
    }
}
